﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.Linq;
using System.Linq;
using System.Text;
using IntraVision.Web;
using IntraVision.Web.Filter;
using IntraVision.Web.Security;
using Model;
using System.Data.Linq.SqlClient;

[AllowedRole("IsAdmin"), System.Runtime.InteropServices.GuidAttribute("93048147-9760-4E66-A165-D68E05E4BBC5")]
public class CompanyController : TableController<NotarialServiceDataContext, Company>
{
    private string[] searchIgnoreWords = { "оао", "ооо", "зао", "ooo", "\"" };
    bool create = false;
    bool isUnionMode = false;
    private int? personId;

    public CompanyController() { }

    #region form

    public override void Create()
    {
        if (!string.IsNullOrEmpty(Request["possiblename"]))
            ViewData["name"] = Request["possiblename"];
        base.Create();
    }

    public override void View(string entityid)
    {
        if (!string.IsNullOrEmpty(Request["popup"]) && Request["popup"] == "true")
        {
            LayoutPath = "~/views/layouts/popup.haml";
            TemplatePath = "~/views/company/form.haml";

            if (string.IsNullOrEmpty(Request["edit"]))
            {
                ViewData["popup"] = true;
                ViewData["readonly"] = true;
            }
            else
                ViewData["edit"] = true;

            ViewData["isexternal"] = true;
        }
        base.View(entityid);
    }

    protected override void EntityLoaded(NotarialServiceDataContext dc, Company entity)
    {
        RegisterScript("jquery.multipleselect.js", "table.js", "jquery.autocomplete.js", "jquery.ui.packed.js");
        RegisterStylesheet("autocomplete/autocomplete.css");

        if (entity.Id == 0) //create
            ViewData["queryParams"] = Request.Url.Query;

        if (!string.IsNullOrEmpty(Request["opener"]))
            ViewData["opener"] = Request["opener"];

        if (!string.IsNullOrEmpty(Request["returntoopeneraftersave"]))
            ViewData["returnToOpenerAfterSave"] = true;

        ViewData["persons"] = (from c in dc.Persons where c.CompanyPersons.Any(cp => cp.CompanyId == entity.Id) orderby c.Name select c).ToList();

        CheckIsExternal();

        string hashKey = string.Empty;
        if (isUnionMode)
            ViewData["possiblelist"] = PrepareUnionPossibleItems(dc, entity, true, ref hashKey);
    }

    protected override void BeforeSubmit(NotarialServiceDataContext dc, Company company)
    {
        create = (company.Id == 0);
        var cidStr = Request["unioncompanyid"];

        if (!string.IsNullOrEmpty(cidStr))
        {
            int cid = 0;
            if (int.TryParse(cidStr, out cid) && cid > 0)
            {
                var srcCompany = dc.Companies.FirstOrDefault(c => c.Id == cid);
                if (!string.IsNullOrEmpty(Request["isunionorders"]))
                {
                    foreach (var o in srcCompany.OrderClientCompanies)
                        o.CompanyId = company.Id;
                    foreach (var o in srcCompany.OrderResponsibleCompanies)
                        o.CompanyId = company.Id;
                }
                if (!string.IsNullOrEmpty(Request["isunionpersons"]))
                {
                    foreach (var o in srcCompany.CompanyPersons.Where(cp => !company.CompanyPersons.Any(c => c.PersonId == cp.PersonId)))
                        company.CompanyPersons.Add(new CompanyPerson { Person = o.Person });
                    dc.CompanyPersons.DeleteAllOnSubmit(srcCompany.CompanyPersons);
                }
                srcCompany.IsArchive = true;
                if (!string.IsNullOrEmpty(Request["isdeletesrc"]))
                    dc.Companies.DeleteOnSubmit(srcCompany);
            }
        }
    }

    protected override void AfterSubmit(NotarialServiceDataContext dc, Company entity)
    {
        Logger.WriteLog(dc, (create) ? LogOperationType.ClientCreate : LogOperationType.ClientChange, (Session["User"] as User).Id, null, null);
    }

    protected override void ReturnAfterSave(string page)
    {
        Response.Redirect((Session["companymode"] as string) ?? "client.ivp/list");
    }

    private void CheckIsExternal()
    {
        if (!string.IsNullOrEmpty(Request["isexternal"]) && Request["isexternal"].ToLower() == "true")
        {
            LayoutPath = "~/views/layouts/popup.haml";
            TemplatePath = "~/views/company/form.haml";
            if (string.IsNullOrEmpty(Request["edit"]))
            {
                ViewData["popup"] = true;
            }
            else
                ViewData["edit"] = true;

            ViewData["isexternal"] = true;
        }
    }
    
    #endregion

    #region list

    public void UnionList()
    {
        isUnionMode = true;
        _ActionKey = Action;
        LayoutPath = "~/views/layouts/page.haml";
        TemplatePath = "~/views/company/unionlist.haml";
        ViewData["hidecb"] = true;
        ProcessTable();
    }

    [AllowedRole("IsAdmin")]
    public void Select()
    {
        ViewData["hidecb"] = ViewData["popup"] = true;
        RegisterScript("table.js", "jquery.multipleselect.js", "user/select.js");

        _ActionKey = Action;
        if (String.IsNullOrEmpty(Request["nolayout"]))
        {
            LayoutPath = "~/views/layouts/popup.haml";
            TemplatePath = "~/views/person/select.haml";
        }
        else TemplatePath = "~/views/_table/table.haml";

        ProcessTable();
    }

    protected override IQueryable<Company> Paginate(IQueryable<Company> query)
    {
        if (isUnionMode)
            return query;
        return base.Paginate(query);
    }

    public void LoadPersonCompanies()
    {
        if (!string.IsNullOrEmpty(Request["personid"]))
            personId = Convert.ToInt32(Request["personid"]);

        _ActionKey = Action;
        //ViewData["hidecb"] = true;

        TemplatePath = "~/views/company/companyperson.haml";
        LayoutPath = "none";

        ProcessTable();
    }

    protected override IQueryable ConvertQueryToResult(NotarialServiceDataContext dc, IQueryable<Company> query)
    {
        string hashKey = string.Empty;
        if (isUnionMode)
            return (from q in query.ToList()
                    select new SimpleObject
                    {
                        Id = q.Id,
                        Name = ToHtml(PrepareUnionPossibleItems(dc, q, false, ref hashKey), q),
                        HashKey = hashKey
                    }).Where(c => c.Name.IndexOf("<li>") != c.Name.LastIndexOf("<li>"))
                    .Distinct(new SimpleObjectNameComparer())
                    .AsQueryable();

        return (from q in query
                select new
                {
                    Id = q.Id,
                    Name = q.Name
                });
    }

    protected override void CreateFilterConditions(NotarialServiceDataContext dc)
    {
        Filter = new Filter<Company>();
        bool isSelect = ViewData.ContainsKey("ActionKey") && ViewData["ActionKey"].ToString() == "select";

        Filter.Conditions.Add(new UserRelationFilterCondition<Company>(
            "CompanyPersons",
            "CompanyId",
            "Физические лица",
            (from c in dc.Persons orderby c.Name select new { Id = c.Id, Name = c.FIO }),
            -1,
            "",//"order.ivp/findclients", 
            "person.ivp/select?reset=true"));
    }

    protected override IQueryable<Company> CustomFilter(NotarialServiceDataContext dc, IQueryable<Company> query)
    {
        if (personId.HasValue)
            return query.Where(q => q.CompanyPersons.Any(cp => cp.PersonId == personId.Value));
        return base.CustomFilter(dc, query);
    }

    #endregion

    #region union 

    [AllowedRole("IsAdmin")]
    public void Union(string entityid)
    {
        TemplatePath = "~/views/company/union.haml";
        isUnionMode = true;
        base.View(entityid);
    }

    [AllowedRole("IsAdmin")]
    public void LoadUnionSource(string entityid)
    {
        TemplatePath = "~/views/company/_unionsource.haml";
        ViewData["issourcecompany"] = true;
        base.View(entityid);
    }

    protected IList<Company> PrepareUnionPossibleItems(NotarialServiceDataContext dc, Company company, bool excludeSelf, ref string hashKey)
    {
        var result = new List<Company>();
        var name = !string.IsNullOrEmpty(company.Name) ? RemoveIgnoreWordsForSearch(company.Name.Trim().ToLower()) : string.Empty;
        if (!string.IsNullOrEmpty(name))
        {
            var search = string.Format("%{0}%", name.Substring(0, (name.Length < 5) ? name.Length : 5).Trim());
            result = dc.Companies.Where(c => (!excludeSelf || c.Id != company.Id) && SqlMethods.Like(c.Name.ToLower().Trim(), search)).ToList();
        }
        if (result != null && result.Count > 0)
            hashKey = string.Join(",", result.OrderBy(r => r.Id).Select(r => r.Id.ToString()).ToArray());
        return result;
    }

    protected string ToHtml(IList<Company> list, Company first)
    {
        var result = new StringBuilder();
        result.Append("<ul>");
        result.Append(string.Format("<li>{0}</li>", first.ToUnionLink()));
        foreach (var c in list.Where(l => l.Id != first.Id))
            result.Append(string.Format("<li>{0}</li>", c.ToUnionLink()));
        result.Append("</ul>");
        return result.ToString();
    }

    protected string RemoveIgnoreWordsForSearch(string name)
    {
        if (string.IsNullOrEmpty(name)) return name;
        var result = name.ToLower();
        foreach (var w in this.searchIgnoreWords)
            result = result.Replace(w, string.Empty);
        return result.ToString().Trim();
    }

    #endregion
}
